package com.edu.base.ums.member.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.edu.base.common.AuthUtil;
import com.edu.base.common.SystemService;
import com.edu.base.common.WeiboUtil;
import com.edu.base.common.utils.DateUtils;
import com.edu.base.common.utils.IdGen;
import com.edu.base.common.vo.VerifyCodeEnum;
import com.edu.base.rest.AppBackUserLoginController;
import com.edu.base.rest.service.AppLoginService;
import com.edu.base.rest.service.AppTokenService;
import com.edu.base.rest.utils.QQUtil;
import com.edu.base.ums.member.domain.ClsMember;
import com.edu.base.ums.member.domain.QQAccessToken;
import com.edu.base.ums.member.mapper.ClsMemberMapper;
import com.edu.base.ums.member.service.IClsMemberService;
import com.edu.base.ums.memberShareReward.domain.ClsMemberShareReward;
import com.edu.base.ums.memberShareReward.mapper.ClsMemberShareRewardMapper;
import com.edu.base.ums.student.domain.ClsMemberStudent;
import com.edu.base.ums.student.mapper.ClsMemberStudentMapper;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.UUIDUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 会员 Service业务层处理
 * 
 * @author lzs
 * @date 2021-05-24
 */
@Service
public class ClsMemberServiceImpl implements IClsMemberService {
	@Autowired
	private ClsMemberMapper clsMemberMapper;

	@Autowired
	private ClsMemberStudentMapper clsMemberStudentMapper;

	@Autowired
	private AppLoginService appLoginService;

	@Autowired
	private RedisCache redisCache;
	
 	@Value("${weixin.appId}")
 	private String  weixinAppId;
 	
	@Value("${weixin.appsecret}") 
 	private String  weixinAppsecret;
	
	@Value("${qq.appId}")
 	private  String  QQ_APP_ID;
 	
	@Value("${qq.appQQSecret}") 
 	private  String  QQ_APP_SECRET;
	

	
	@Autowired
	private AppTokenService tokenService;
	@Autowired
	private ClsMemberShareRewardMapper shareRewardMapper;
	
//	@Autowired
//	private QQUtil qqUtil;
 	

	/**
	 * 查询会员
	 * 
	 * @param id
	 *            会员 ID
	 * @return 会员
	 * 
	 */
	@Override
	public ClsMember selectClsMemberById(String id) {

		return clsMemberMapper.selectClsMemberById(id);
	}

	/**
	 * 查询会员 列表
	 * 
	 * @param clsMember
	 *            会员
	 * 
	 * @return 会员
	 * 
	 */
	@Override
	public List<ClsMember> selectClsMemberList(ClsMember clsMember) {
		return clsMemberMapper.selectClsMemberList(clsMember);
	}

	/**
	 * 新增会员
	 * 
	 * @param clsMember
	 *            会员
	 * @return 结果
	 */
	@Override
	public int insertClsMember(ClsMember clsMember) {
		clsMember.setId(UUIDUtils.getUUID());
		clsMember.setCreateDate(new Date());
		
		// TODO 维护学生档案信息
		ClsMemberStudent cms = new ClsMemberStudent();

		// 拿不到当前用户，这个是注册，没有当前用户
		// cms = (ClsMemberStudent) BeanUtils.initBeanPublicProperties(cms, "add");
		cms.setId(IdUtils.simpleUUID());
		cms.setCreateDate(new Date());
		// cms.setCreateTime(new Date());

		cms.setMemberId(clsMember.getId());

		cms.setCourseId(clsMember.getCourseId());
		cms.setCourseClassesId(clsMember.getCourseClassesId());
		cms.setEnglishlevel(clsMember.getEnglishlevel());
		cms.setSchoolId(clsMember.getSchoolId());
		cms.setGrades(clsMember.getGrades());
		cms.setClasses(clsMember.getClasses());
		clsMemberStudentMapper.insertClsMemberStudent(cms);
		clsMember.setDelFlag("0");
		return clsMemberMapper.insertClsMember(clsMember);
	}

	/**
	 * 更新会员积分
	 * @param inviteCode
	 * @return
	 */
	@Override
	public TimerTask udateMemberScore(String newMemberId,String phone,String inviteCode) {
		return new TimerTask() {
			@Override
			public void run() {
				ClsMember clsMember = new ClsMember();
				clsMember.setInviteCode(inviteCode);
				List<ClsMember> clsMembers = clsMemberMapper.selectClsMemberList(clsMember);
				if(clsMembers!=null && clsMembers.size()>0){
					final ClsMember cmember = clsMembers.get(0);
					clsMember.setScore(BigDecimal.valueOf(Double.parseDouble(DictUtils.getDictValue("share_score","score"))));
					clsMember.setId(cmember.getId());
					//初始化积分奖励
					ClsMemberShareReward shareReward = new ClsMemberShareReward();
					shareReward.setMemberId(cmember.getId());
					shareReward.setNewMemberId(newMemberId);
					shareReward.setNewMemberPhone(phone);
					shareReward.setRewardScore(clsMember.getScore());
					shareReward.setRewardType("1");
					shareReward.setCreateTime(new Date());

					updateMemberInfo(clsMember,shareReward);
				}
			}
		};
	}

	@Transactional
	public void updateMemberInfo(ClsMember clsMember, ClsMemberShareReward shareReward){
		clsMemberMapper.updateClsMember(clsMember);
		shareRewardMapper.insertClsMemberShareReward(shareReward);
	}

	/**
	 * 修改会员
	 * 
	 * @param clsMember
	 *            会员
	 * @return 结果
	 */
	@Override
	public int updateClsMember(ClsMember clsMember) {
		//clsMember = (ClsMember) BeanUtils.initBeanPublicProperties(clsMember, "update");
		// TODO 维护学生档案信息 --先删后增
		ClsMemberStudent clsMemberStudent = clsMemberStudentMapper.selectClsMemberStudentByMemberId(clsMember.getId());
		if (clsMemberStudent != null) {
			clsMemberStudentMapper.deleteClsMemberStudentByMemberId(clsMember.getId());
		}
		ClsMemberStudent cms = new ClsMemberStudent();
		//cms = (ClsMemberStudent) BeanUtils.initBeanPublicProperties(cms, "add");
		cms.setId(UUIDUtils.getUUID());
		cms.setCreateDate(new Date());
		//cms.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
		cms.setMemberId(clsMember.getId());
		cms.setCourseId(clsMember.getCourseId());
		cms.setCourseClassesId(clsMember.getCourseClassesId());
		cms.setEnglishlevel(clsMember.getEnglishlevel());
		cms.setSchoolId(clsMember.getSchoolId());
		cms.setGrades(clsMember.getGrades());
		cms.setClasses(clsMember.getClasses());
		clsMemberStudentMapper.insertClsMemberStudent(cms);
		
		// TODO 针对用户会员期限
		if(StringUtils.isNotBlank(clsMember.getDuetime())) {
			this.handleTime(clsMember);
		}

		return clsMemberMapper.updateClsMember(clsMember);
	}

	private void handleTime(ClsMember clsMember) {
		ClsMember cls = clsMemberMapper.selectClsMemberById(clsMember.getId());
		if(cls.getHandleDate() != null && cls.getExpireDate() != null) {
			// TODO  在到期时间基础上，增加某几月，
			clsMember.setExpireDate(DateUtils.stepMonth(cls.getExpireDate(), Integer.valueOf(clsMember.getDuetime())));
		}
	}

	/**
	 * 批量删除会员 ---用户做逻辑删除
	 * 
	 * 
	 * @param ids
	 *            需要删除的会员 ID
	 * @return 结果
	 */
	@Override
	public int deleteClsMemberByIds(String[] ids) {
		return clsMemberMapper.deleteClsMemberByIds(ids);
	}

	/**
	 * 删除会员 信息---用户做逻辑删除
	 * 
	 * @param id
	 *            会员 ID
	 * @return 结果
	 */
	@Override
	public int deleteClsMemberById(String id) {
		return clsMemberMapper.deleteClsMemberById(id);
	}

	/**
	 * 根据手机号码查询会员是否存在
	 * 
	 * @param phone
	 *
	 * @return 会员
	 */
	@Override
	public List<ClsMember> selectClsMemberByPhone(String phone) {
		List<ClsMember> list = clsMemberMapper.selectClsMemberByPhone(phone);
		return list;
	}

	/**
	 * 判断登录名是否存在
	 */
	@Override
	public List<ClsMember> selectClsMemberByUserName(String username) {
		List<ClsMember> list = clsMemberMapper.selectClsMemberByUserName(username);
		return list;
	}

	/**
	 * 修改启用和禁用状态
	 */
	@Override
	public int changeClsMemberStatus(ClsMember clsMember) {
		return clsMemberMapper.updateClsMember(clsMember);
	}

	@Override
	public ClsMember checkThirdPartyBindingUser(String thirdType, String thirdPartyId) {
		ClsMember clsMember = new ClsMember();
		clsMember.setDelFlag("0");
		clsMember = this.setThirdValue(clsMember, thirdType, thirdPartyId);
		List<ClsMember> clsMemberList = this.clsMemberMapper.selectClsMemberList(clsMember);
		if (null != clsMemberList && clsMemberList.size() > 0) {
			return clsMemberList.get(0);
		} else {
			return null;
		}
	}

	/**
	 * @Description：主要用于根据第三方类型来存对应的字段值
	 * @since: 2018年9月6日 下午1:53:59
	 */
	private ClsMember setThirdValue(ClsMember clsMember, String thirdType, String thirdPartyId) {
		if (VerifyCodeEnum.WECHAT_BIND.getMessType().equals(thirdType)) {// 第三方类型为微信时
			clsMember.setWeixinOpenid(thirdPartyId);
		} else if (VerifyCodeEnum.WEIBO_BIND.getMessType().equals(thirdType)) {// 第三方类型为微博时
			clsMember.setBlogToken(thirdPartyId);
		} else if (VerifyCodeEnum.QQ_BIND.getMessType().equals(thirdType)) {// 第三方类型为qq时
			clsMember.setQqToken(thirdPartyId);
		} else {//// 第三方类型为苹果
			clsMember.setAppleId(thirdPartyId);
		}
		return clsMember;
	}

	/**
	 * @Description：已经绑定过的第三方直接登陆
	 * @author: liujintao
	 * @since: 2018年9月6日 下午2:49:19
	 * @param appUser
	 *            用户对象
	 */
	@Override
	public Map<String, Object> bindingLoginSetToken(ClsMember clsMember) {
		Map<String, Object> dataMap = new HashMap<String, Object>();
		String uuid = IdUtils.simpleUUID();
		// String token = appLoginService.login(clsMember.getUserName(),
		// clsMember.getPassWord(), uuid);
		// 将用户的token保存到缓存中，key为用户id，vlue为token
		redisCache.setCacheObject(String.valueOf(clsMember.getId()), uuid, 15 * 24 * 60 * 60, TimeUnit.SECONDS);
		ClsMember clsMember1 = this.clsMemberMapper.selectClsMemberById(clsMember.getId());
		dataMap.put("memberType", clsMember1.getMemberType());
		dataMap.put("id", clsMember1.getId());
		// dataMap.put("tokenId", token);
		return dataMap;
	}

	// -----------------------------------------------------------------------二级方法----------------------------------------------------------------
	/**
	 * @Description： 用户绑定第三方/绑定第三方并注册
	 * 
	 * @author: liujintao
	 * @since: 2018年9月6日 下午1:48:31
	 * @param mobile
	 *            手机号
	 * @param thirdPartyId
	 *            第三方id
	 * @param loginType
	 *            第三方登录类型
	 * @param nickName
	 *            昵称 (第三方)
	 * @param headPortrait
	 *            头像(第三方)
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	@Override
	public ClsMember userBindingThirdParty(String thirdPartyId, String phone, String thirdType, String passWord,
			String nickName, String icon) {
		// String thirdPartyId = params.getDynaValue("thirdPartyId",String.class);//
		// 第三方id
		// String phone = params.getDynaValue("phone",String.class);// 手机号
		// String thirdType =
		// params.getDynaValue("thirdType",String.class);//绑定类型，目前是微信、qq、微博
		// String passWord = params.getPassword();
		// UmsMember exist = umsMemberService.findUserByPhone(phone);// 根据手机号获取用户
		List<ClsMember> clsMemberList = this.clsMemberMapper.selectClsMemberByPhone(phone);
		if (CollectionUtils.isNotEmpty(clsMemberList)) {// 如果用户不为空,则已有用户 仅需要将第三方和用户绑定即可
			ClsMember exist = clsMemberList.get(0);
			exist = this.setThirdValue(exist, thirdType, thirdPartyId);// 存入第三方id
			exist.setNickName(nickName);// 第三方昵称
			exist.setIcon(icon);// 第三方头像
			// exist.setPassword(systemService.entryptPassword(passWord));//密码
			this.clsMemberMapper.updateClsMember(exist);// 保存修改
			return exist;
		} else {// 用户为空,则为新用户注册并绑定密码
			ClsMember newUser = new ClsMember();
			newUser.setId(UUIDUtils.getUUID());
			if (StringUtils.isEmpty(newUser.getIcon()))
				newUser.setIcon(AppBackUserLoginController.defautPhotoUrlStudent);
			newUser.setStatus("1");
			newUser.setSourceType("1");
			this.setThirdValue(newUser, thirdType, thirdPartyId);
			newUser.setPhone(phone);
			newUser.setStatus("1");
			newUser.setIntegration(0L);
			newUser.setBlance(0l);
			newUser.setPassWord(SystemService.entryptPassword(passWord));
			newUser.setLoginTime(new Date());
			this.clsMemberMapper.insertClsMember(newUser);
			return newUser;
		}

	}

	@Override
	public ClsMember insertClsMemberRyByPHone(String phone) {
		ClsMember clsMember = new ClsMember();
		clsMember.setId(UUIDUtils.getUUID());
		clsMember.setStatus("1");
		clsMember.setMemberType("4");
		clsMember.setIntegration(0L);
		clsMember.setBlance(0l);
		clsMember.setSourceType("1");
		clsMember.setCreateTime(new Date());
		clsMember.setUserName(IdGen.getUserName(phone));
		clsMember.setPassWord(SystemService.entryptPassword(phone));// 默认密码
		clsMember.setNickName(phone);
		this.clsMemberMapper.insertClsMember(clsMember);
		return clsMember;
	}
	
	
	/**
	 * @throws
	 * @title weChatLogin
	 * @description 微信授权登录
 	 */
	public AjaxResult weChatLogin(String code) {
		//HashMap<String,Object> map = new HashMap<>();
	    try {
	        //通过第一步获得的code获取微信授权信息
	        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + weixinAppId+ "&secret="
	                + weixinAppsecret + "&code=" + code + "&grant_type=authorization_code";
	        JSONObject jsonObject = AuthUtil.doGetJson(url);
	        String openid = jsonObject.getString("openid");
	        String token = jsonObject.getString("access_token");
	        String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + openid
	                + "&lang=zh_CN";
	        JSONObject userInfo = AuthUtil.doGetJson(infoUrl);

	        //成功获取授权,以下部分为业务逻辑处理了，根据个人业务需求写就可以了
	        if (userInfo != null && openid != null) {
	            String nickname = userInfo.getString("nickname");
	            String headimgurl = userInfo.getString("headimgurl");
	            headimgurl = headimgurl.replace("\\", "");
	            //根据openid查询时候有用户信息
	            List<ClsMember> memberDTO = clsMemberMapper.getMemberInfoByWeixinOpenid(openid);
	            if (CollectionUtils.isEmpty(memberDTO)) {
	                //没有绑定用户请前往绑定
 	                /*map.put("state", "1");
	                map.put("openid", openid);
	                map.put("token", "");
	                map.put("nickname", nickname);
	                map.put("photo", headimgurl);*/ 
	                //返回用户信息
	                ClsMember clsMember = new  ClsMember();
	                clsMember.setId(UUIDUtils.getUUID());
	                clsMember.setWeixinState("1");
	                clsMember.setWeixinOpenid(openid);
	                clsMember.setToken("");
	                clsMember.setWeixinNickName(nickname);
	                clsMember.setIcon(headimgurl);
	                //clsMember.setUserName("wx_"+IdUtils.fastSimpleUUID());
	                clsMemberMapper.insertClsMember(clsMember);
	                return AjaxResult.success(clsMember);
	            } else { 
	                //已经绑定用户信息直接登录
	            	ClsMember userInfos =memberDTO.get(0);
 	                String weixinToken = tokenService.token(userInfos.getUserName(), userInfos.getPassWord());
	                // 缓存权限
	                Map<String, String> httpUrl = new HashMap<>();
	                httpUrl.put("kylin", "shuoye.com:8484");
	                //authHandler.setRoleUrl(memberDTO.getId().toString(), httpUrl); 
	                /*map.put("state", "2");
	                map.put("openid", openid);
	                map.put("token", weixinToken); */
	                userInfos.setWeixinState("2");
	                userInfos.setWeixinOpenid(openid);
	                userInfos.setToken(weixinToken); 
	                userInfos.setWeixinNickName(nickname);
	                userInfos.setIcon(headimgurl);
	                clsMemberMapper.updateClsMember(userInfos); 
	                return AjaxResult.success(userInfos);
	            }
	        } else {
	            return AjaxResult.error("登录失败");
	        }
	    } catch (Exception e) {
	        return  AjaxResult.error("登录失败");
	    }
 
	}

	@Override
	public AjaxResult qqLogin(String code, String state) {
		try {
			if (code != null && !"".equals(code)) {
				QQUtil qqUtil =  new  QQUtil(QQ_APP_ID,QQ_APP_SECRET);
				QQAccessToken qqAccessToken = qqUtil.getQQLoginAccessToken(code);
				if (qqAccessToken.getAccessToken().equals("")) {
					// 我们的网站被CSRF攻击了或者用户取消了授权
					// 做一些数据统计工作
					System.out.print("没有获取到响应参数");
					// 跳转返回地址
					return AjaxResult.error("登录失败,未获取到AccessToken，请重新进行QQ授权登录");
				} else {
					QQAccessToken qqAccessToken2 = qqUtil.refreshQQAccessToken(qqAccessToken.getRefreshToken());
					String accessToken = qqAccessToken2.getAccessToken();
					String openId = qqUtil.getQQOpenId(accessToken);
					JSONObject  jSONObject =qqUtil.getUserInfo(accessToken, openId);
					// String referer = redisHandle.get(state).toString();
					// redisHandle.set(accessToken, referer, 60 * 30L);
					// redisHandle.remove(state);
					// getResponse().sendRedirect("https://www.zwqh.top/account/getQQUserInfo?qqAccessToken="
					// + accessToken);
					ClsMember  clsMember = (ClsMember) jSONObject.get("user");
					if(clsMember != null) {
			            List<ClsMember> memberQQDTO = clsMemberMapper.getMemberInfoByQqOpenid(clsMember.getQqToken());
			            if(CollectionUtils.isNotEmpty(memberQQDTO)) {
			            	String id = memberQQDTO.get(0).getId();
			            	clsMember.setId(id);
			            	clsMemberMapper.updateClsMember(clsMember);
			            }else {
			                clsMember.setId(UUIDUtils.getUUID()); 
			            	clsMemberMapper.insertClsMember(clsMember);
			            }

						return AjaxResult.success(clsMember); 
					}else {
						String msg = (String) jSONObject.get("msg");
						return AjaxResult.error(msg); 
					} 
					
				}
			} else {
				return AjaxResult.error("登录失败,缺少code参数");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return AjaxResult.success();
	}

	@Override
	public AjaxResult wbLogin(String error_code, String code, String state) {

		if (StringUtils.isNotBlank(error_code)) {
			return AjaxResult.error("登录失败,微博授权失败");
		} else {
			try { 
				String access_token = "";
				String expires_in = "";
				String uid = "";
				if (WeiboUtil.STATE.equals(state)) {
					// 获取token
					WeiboUtil weiboUtil = new WeiboUtil();
					JSONObject token = weiboUtil.getAccessToken(code);
					access_token = token.getString("access_token");
					uid = token.getString("uid");
					expires_in = String.valueOf(token.getIntValue("expires_in"));
				} else {
					return AjaxResult.error("登录失败,微博授权失败");
				}
				// 查询该用户信息
				List<ClsMember> clsMemberList = clsMemberMapper.findWeiboByIdentifier(uid);
				ClsMember clsMember = new ClsMember();
				if (clsMemberList != null && clsMemberList.size() > 0) {
					clsMember = clsMemberList.get(0);
				} else {
					// 获取用户信息
					WeiboUtil weiboUtil = new WeiboUtil();
					JSONObject userInfo = weiboUtil.getUserInfo(access_token, uid);
					// logger.info("用户信息"+userInfo);
					String nickname = userInfo.getString("screen_name");
					String profile_image_url = userInfo.getString("profile_image_url");
					String gender = "f".equals(userInfo.getString("gender")) ? "1" : "0";

					// 向第三方登录表中添加数据
					clsMember.setId(UUIDUtils.getUUID());
					//String master_id = UUIDUtils.getUUID();
					// user.setMaster_id(master_id);
					// user.setIdentity_type("weibo");
					// user.setIdentifier(uid);
					// user.setCredential(access_token);
					// user.setExpires_in(expires_in);
					// user.setStatus("0");
					// oauthUserService.insert(user);

					// 向用户表中添加默认数据
					// Master masterUser = new Master();
					// masterUser.setId(master_id);
					clsMember.setWeiboNickName(nickname);
					clsMember.setIcon(profile_image_url);
					clsMember.setGender(gender);
					// 由于第三方登录没有用户名密码，而且该字段在数据库中不为空，在此设置默认用户名密码
					clsMember.setUserName("wbu" + access_token.substring(0, 9));
					clsMember.setPassWord("wbp" + access_token.substring(0, 9));
					clsMemberMapper.insertClsMember(clsMember);
				}
				return AjaxResult.success(clsMember);
			} catch (Exception e) {
				e.printStackTrace();
				return AjaxResult.error("登录失败,微博授权失败");
			}
		}
	}

	/**
	 * 办理会员
	 */
	@Override
	public void applyMemberShip(ClsMember clsMember, Integer memberMonth) {
		if(clsMember.getExpireDate() != null) {
			// TODO  在到期时间基础上，增加某几月，
			clsMember.setExpireDate(DateUtils.stepMonth(clsMember.getExpireDate(), memberMonth));
		}else {
			clsMember.setHandleDate(DateUtils.getNow());
			Date  expireDat = DateUtils.formatDateToDate(new Date(), "yyyy-MM-dd");
			clsMember.setExpireDate(DateUtils.stepMonth(expireDat, memberMonth));
		}
		clsMemberMapper.updateClsMember(clsMember);
		
	} 
}
